package com.yanqu.road.server.manger.activity.toyhouse;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.toyhouse.ToyHouseOrder;
import com.yanqu.road.entity.activity.toyhouse.ToyHouseOrderProg;
import com.yanqu.road.entity.activity.toyhouse.config.ToyHouseConfig;
import com.yanqu.road.entity.activity.toyhouse.config.ToyHouseOrderConfig;
import com.yanqu.road.entity.activity.toyhouse.config.ToyHouseScoreConfig;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.bussiness.activity.ToyHouseActivityBusiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.toyhouse.ToyHouseModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ToyHouseMgr extends TempMgr {

    private static ToyHouseConfig toyHouseConfig = null;

    public static void reloadActivityData() {
        getLogger().info("reload ToyHouseMgr start");
        List<ActivityInfo> list = NormalActivityMgr.getOpenActivityInfoList(eActivityType.ToyHouse.getValue());
        if (list.isEmpty()) {
            getLogger().info("reload ToyHouseMgr finish, no activity in show time.");
            toyHouseConfig = null;
            return;
        }

        ActivityInfo activityInfo = list.get(0);
        int activityId = activityInfo.getActivityId();
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityId);

        ToyHouseConfig tmpConfig = new ToyHouseConfig();
        tmpConfig.setActivityInfo(activityInfo);
        tmpConfig.setBlockConfigMap(ToyHouseActivityBusiness.getToyHouseBlockConfigMap(activityId));
        tmpConfig.setCombConfigMap(ToyHouseActivityBusiness.getToyHouseCombConfigMap(activityId));
        tmpConfig.setOrderConfigMap(ToyHouseActivityBusiness.getToyHouseOrderConfigMap(activityId));
        tmpConfig.setScoreConfigMap(ToyHouseActivityBusiness.getToyHouseScoreConfigMap(activityId));
        List<Integer> energyParamList = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_ENERGY_PARAM.getName()).getIntListValue(";");
        tmpConfig.setMaxEnergy(energyParamList.get(0));
        tmpConfig.setEnergyRecTime(energyParamList.get(1) * 1000L);
        tmpConfig.setEnergyRecCount(energyParamList.get(2));
        tmpConfig.setBlockWeightAddList(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_CREATE_BLOCK_WEIGHT_LIST.getName()).getIntListValue(";"));
        List<Integer> scoreParamList = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_ELIMINATE_SCORE_PRAM.getName()).getIntListValue(";");
        Map<Integer, Integer> scoreParamMap = new ConcurrentHashMap<>();
        scoreParamMap.put(1, scoreParamList.get(0));
        scoreParamMap.put(8, scoreParamList.get(1));
        tmpConfig.setScoreGetMap(scoreParamMap);
        List<Integer> energyCostList = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_COST_ENERGY_PARAM.getName()).getIntListValue(";");
        Map<Integer, Integer> energyCostMap = new ConcurrentHashMap<>();
        energyCostMap.put(1, energyCostList.get(0));
        energyCostMap.put(8, energyCostList.get(1));
        tmpConfig.setEnergyCostMap(energyCostMap);
        String multiParam = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_MULTIPLE_MODE_PARAM.getName()).getValue();
        List<String> multiParam2 = StringUtils.stringToStringList(multiParam, "\\|");
        Map<Integer, List<Integer>> multiUnlockMap = new ConcurrentHashMap<>();
        for (String multiParam3 : multiParam2) {
            List<Integer> multiList = StringUtils.stringToIntegerList(multiParam3, ";");
            List<Integer> value = new ArrayList<>();
            value.add(multiList.get(1));
            value.add(multiList.get(2));
            multiUnlockMap.put(multiList.get(0), value);
        }
        tmpConfig.setMultiUnlockMap(multiUnlockMap);
        tmpConfig.setGuideOrderId(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_GUIDE_PARAM.getName()).getIntValue());
        List<Integer> initBlockList = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_INIT_BLOCK.getName()).getIntListValue(",");
        int[] initBlockArr = initBlockList.stream().mapToInt(Integer::intValue).toArray();
        tmpConfig.setInitBlock(initBlockArr);
        List<Integer> initBlockMultiList = activityConfigMap.get(eActivityConfigType.TOY_HOUSE_INIT_BLOCK_MULTI.getName()).getIntListValue(",");
        int[] initBlockMultiArr = initBlockMultiList.stream().mapToInt(Integer::intValue).toArray();
        tmpConfig.setInitBlock8(initBlockMultiArr);

        tmpConfig.setInitOrderProgress(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_INIT_ORDER_PROGRESS.getName()).getValue());
        PropertyHelper.parseStringToProperty(tmpConfig.getInitOrderProgress()); // 校验下格式

        tmpConfig.setScoreId(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_SCORE_ITEM_ID.getName()).getIntValue());
        tmpConfig.setEnergyId(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_ENERGY_ITEM_ID.getName()).getIntValue());
        tmpConfig.setCandyId(activityConfigMap.get(eActivityConfigType.TOY_HOUSE_SPECIAL_SCORE_ITEM_ID.getName()).getIntValue());

        toyHouseConfig = tmpConfig;

        // 在线玩家操作
        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            gamePlayer.getModule(ToyHouseModule.class).initAndSyncData();
        }

        getLogger().info("reload ToyHouseMgr finish, activityId {}", toyHouseConfig.getActivityInfo().getActivityId());
    }

    public static ToyHouseConfig getConfig() {
        return toyHouseConfig;
    }

    public static ActivityInfo getActivityInfo() {
        return toyHouseConfig == null ? null : toyHouseConfig.getActivityInfo();
    }

    public static ToyHouseOrder getRandomNewOrder(ToyHouseConfig config, RandomHelper randomHelper, int multi) {
        List<ToyHouseOrderConfig> orderConfigList = new ArrayList<>();
        for (ToyHouseOrderConfig orderConfig : config.getOrderConfigMap().values()) {
            if (orderConfig.getMulti() == multi) {
                orderConfigList.add(orderConfig);
            }
        }

        if (orderConfigList.isEmpty()) {
            getLogger().error("activity {} can not find order config by multi {}", config.getActivityInfo().getActivityId(), multi);
            return null;
        }

        List<Integer> weightList = orderConfigList.stream().map(ToyHouseOrderConfig::getWeight).collect(Collectors.toList());
        int index = randomHelper.getSafeRandomIndexByWeight(weightList);
        ToyHouseOrderConfig orderConfig = orderConfigList.get(index);

        return getNewOrder(orderConfig);
    }

    public static ToyHouseOrder getNewOrder(ToyHouseOrderConfig orderConfig) {
        Map<Integer, ToyHouseOrderProg> progMap = new ConcurrentHashMap<>();
        for (Map.Entry<Integer, BigInteger> entry : orderConfig.getBlockProp().getGoods().entrySet()) {
            progMap.put(entry.getKey(), new ToyHouseOrderProg(entry.getKey(), entry.getValue().intValue(), 0));
        }
        return new ToyHouseOrder(orderConfig.getOrderId(), progMap);
    }

    /**
     * 复制一份格子数据
     */
    public static int[][] getCopyBlockList(int[][] list) {
        int[][] result = new int[list.length][];
        for (int i = 0; i < list.length; i++) {
            result[i] = list[i].clone();
        }
        return result;
    }

    /**
     * 计算第x轮的格子积分（x从1开始）
     */
    public static long calBlockScore(ToyHouseConfig config, int round, int multi) {
        // 基础积分
        BigDecimal baseScore = BigDecimal.valueOf(config.getScoreGetMap().get(multi));
        // 放大倍数
        int scoreAdd = 0;
        Map<Integer, ToyHouseScoreConfig> scoreConfigMap = config.getScoreConfigMap();
        if (scoreConfigMap.containsKey(round)) {
            scoreAdd = scoreConfigMap.get(round).getScoreAdd();
        } else {
            // 没有配置的话，就取最大值
            int maxRound = -1;
            for (ToyHouseScoreConfig scoreConfig : scoreConfigMap.values()) {
                if (scoreConfig.getContinuousNum() > maxRound) maxRound = scoreConfig.getContinuousNum();
            }
            scoreAdd = scoreConfigMap.get(maxRound).getScoreAdd();
        }
        // 结果
        return baseScore.multiply(BigDecimal.valueOf(1000 + scoreAdd)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).longValue();
    }

    public static ToyHouseOrder getCopyOrder(ToyHouseOrder order) {
        ToyHouseOrder tmp = new ToyHouseOrder();
        tmp.setoId(order.getoId());
        tmp.setProgMap(new ConcurrentHashMap<>());
        for (ToyHouseOrderProg prog : order.getProgMap().values()) {
            tmp.getProgMap().put(prog.getbId(), prog.clone());
        }
        return order;
    }

    /**
     * 判断订单状态
     *
     * @return 1进行中，2已完成
     */
    public static boolean isOrderFinish(ToyHouseOrder copyOrder) {
        for (ToyHouseOrderProg orderProg : copyOrder.getProgMap().values()) {
            if (orderProg.getCur() < orderProg.getNeed()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否成就道具
     */
    public static boolean isCandyItem(int itemId) {
        ToyHouseConfig config = getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return config.getCandyId() == itemId;
        }
        return false;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
